home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 1 / your choice.zip / your choice / PRGMMING / VISIONIX / VUARTU.PAS < prev    next >
Pascal/Delphi Source File  |  1993-12-29  |  40KB  |  2,059 lines

  1. {
  2.  ════════════════════════════════════════════════════════════════════════════
  3.  
  4.  Visionix Serial Communictions Unit - 8250/16450/16550 UART (VUART)
  5.    Version 0.8
  6.  Copyright 1991,92,93 Visionix
  7.  ALL RIGHTS RESERVED
  8.  
  9.  ────────────────────────────────────────────────────────────────────────────
  10.  
  11.  ** revision history in reverse chronological order **
  12.  
  13.  Initials  Date      Comment
  14.  ────────  ────────  ────────────────────────────────────────────────────────
  15.  
  16.  mep       11/15/93  First logged revision.
  17.  
  18.  ────────────────────────────────────────────────────────────────────────────
  19. }
  20.  
  21. (*-
  22.  
  23. [TEXT]
  24.  
  25. <Overview>
  26.  
  27. This unit implements functions to interface with the PC/ATs 8250,
  28. 16450, or 16550 Univeral Asychronous Receiver/Transmitter, or UART
  29. chip.  The UART chip is the PCs interface to the RS-232 world.
  30.  
  31. Additionally, this unit impelements a function to interface the UART
  32. functions into the VSERu device-indepednent serial unit.  This function,
  33. UartSerDriverProc, is a serial driver procedure for VDOSu serial channels.
  34.  
  35. UartSerDriverProc can be specified as the serial-driver for a serial
  36. channel by calling VSerDriverNew and specifying UartSerDriverProc
  37. as the serial driver procedure.
  38.  
  39. <Interface>
  40.  
  41. -*)
  42.  
  43.  
  44. Unit VUartU;
  45.  
  46. Interface
  47.  
  48. Uses
  49.  
  50.   VTypesu,
  51.   VSerlu,
  52.   DOS;
  53.  
  54.  
  55.  
  56. Procedure VUartBaudSet(           BaudRate       : LONGINT );
  57.  
  58. Function  VUartBaudGet                                          : LONGINT;
  59.  
  60. Function  VUartInit(              ComPort        : BYTE;
  61.                                   BaudRate       : LONGINT     ): WORD;
  62.  
  63. Procedure VUartDeInit;
  64.  
  65. Procedure VUartDTROn;
  66.  
  67. Procedure VUartDTROff;
  68.  
  69. Function  VUartIsTXReady : BOOLEAN;
  70.  
  71. Function  VUartIsCarrier : BOOLEAN;
  72.  
  73. Function  VUartIsRXReady : BOOLEAN;
  74.  
  75. Function  VUartReadChar  : CHAR;
  76.  
  77. Procedure VUartWriteChar(         Ch             : CHAR );
  78.  
  79. Procedure VUartOutFlush;
  80.  
  81. Procedure VUartOutPurge;
  82.  
  83. Procedure VUartInPurge;
  84.  
  85. Procedure VUartBreak(             DelayMS        : WORD         );
  86.  
  87. Procedure VUartCtsRtsSet(         ON             : BOOLEAN );
  88.  
  89.  
  90. Procedure UartSerDriverProc( SDP : PSerDriverPacket );
  91.  
  92. {────────────────────────────────────────────────────────────────────────────}
  93.  
  94.  
  95. IMPLEMENTATION
  96.  
  97.  
  98. Const
  99.  
  100.  
  101.   cUartClockFreq  = 115200;
  102.  
  103.   cMaxComPort    = 7;
  104.   cInBuffSize    = 8196;
  105.   cInBuffMax     = 8195;
  106.  
  107.   cUartInt       = $14;
  108.   cIntMaskReg    = $21;             { 8259 interrupt mask register }
  109.  
  110.   {----------------------------}
  111.   { 8250/16450/16550 registers }
  112.   {----------------------------}
  113.  
  114.   cUartTHR           = $00;         {                              }
  115.   cUartRBR           = $00;         {                              }
  116.  
  117.   cUartIER           = $01;         { Interrupt Enable Register    }
  118.  
  119.   cUartIIR           = $02;         { Interrupt ID Register        }
  120.   cUartFCR           = $02;         { 16550 FIFO control register  }
  121.  
  122.   cUartLCR           = $03;         { Line Control Register        }
  123.  
  124.   cUartMCR           = $04;         { Modem Control Register       }
  125.  
  126.   cUartLSR           = $05;         { Line Status Register         }
  127.  
  128.   cUartMSR           = $06;         { Modem Status Register        }
  129.  
  130.  
  131.   {---------------------------------}
  132.   { Interrupt Enable Register flags }
  133.   {---------------------------------}
  134.  
  135.   cEnableRcvInt      = $01;         { enable receive interrupt     }
  136.   cEnableXfrInt      = $02;         { enable transfer interrupt    }
  137.   cEnableLSInt       = $04;         { enable line-status interrupt }
  138.   cEnableMSInt       = $08;         { enable modem-status interrupt}
  139.  
  140.   {-----------------------------------}
  141.   { Interrupt ID Register (IIR) Flags }
  142.   {-----------------------------------}
  143.  
  144.   cIntPending        = $01;         { an interrupt is pending      }
  145.  
  146.   cIntIDMask         = $02+$04;     { interrupt ID mask            }
  147.  
  148.   cIntIDLookMSR      = $00;         { interrupt ID=look in MSR     }
  149.   cIntIDXfer         = $02;         { interrupt ID=transfered data }
  150.   cIntIDRcv          = $04;         { interrupt ID=received data   }
  151.  
  152.   cIntFifoTimeout    = $08;         { 16550 FIFO timeout           }
  153.  
  154.   cFifoModeMask      = $40+$80;     { 16550 Mode Status Mask       }
  155.  
  156.   cFifoModeChar      = $00;         { 16550 Mode=char (emu 16450)  }
  157.   cFifoModeDMA       = $40;         { 16550 Mode=type 3 DMA        }
  158.   cFifoModeFifo      = $80+$40;     { 16550 Mode=FIFO enabled      }
  159.  
  160.   {-----------------------------------}
  161.   { FIFO Control Register (FCR) Flags }
  162.   {-----------------------------------}
  163.  
  164.   cFifoEnable        = $01;         { 16550 Fifo Enable flag       }
  165.   cFifoRcvBuffReset  = $02;         { 16550 Reset Receive buffer   }
  166.   cFifoXferBuffReset = $04;         { 16550 Reset Transmit buffer  }
  167.  
  168.   cFifoFTSMask       = $80+$40;     { 16550 FIFO Trigger Size mask }
  169.  
  170.   cFifoFTS1          = $00;         { 16550 FIFO Trig Size=1  byte }
  171.   cFifoFTS4          = $40;         { 16550 FIFO Trig Size=4  bytes}
  172.   cFifoFTS8          = $80;         { 16550 FIFO Trig Size=8  bytes}
  173.   cFifoFTS14         = $80+$40;     { 16550 FIFO Trig Size=14 bytes}
  174.  
  175.  
  176.   {-----------------------------------}
  177.   { Line Control Register( LCR) Flags }
  178.   {-----------------------------------}
  179.  
  180.   cDataBitsMask      = $01+$02;     { Data bits (wordsize) mask    }
  181.   cDataBits5         = $00;         { Data bits = 5                }
  182.   cDataBits6         = $01;         { Data bits = 6                }
  183.   cDataBits7         = $02;         { Data bits = 7                }
  184.   cDataBits8         = $01+$02;     { Data bits = 8                }
  185.  
  186.   cStopBits1         = $00;         { Stop bits = 1                }
  187.   cStopBits2         = $04;         { Stop bits = 2                }
  188.  
  189.   cParityEnable      = $08;         { Enable parity                }
  190.  
  191.   cParityEven        = $10;         { even parity                  }
  192.  
  193.   cStickyParity      = $20;         { sticky parity                }
  194.  
  195.   cBreakOn           = $40;         { turn break on                }
  196.  
  197.   cAccessDivLatch    = $80;         { access divisor latch         }
  198.  
  199.  
  200.  
  201.   {------------------------------------}
  202.   { Modem Control Register (MCR) flags }
  203.   {------------------------------------}
  204.  
  205.   cDTR               = $01;         { Data terminal ready          }
  206.   cRTS               = $02;         { Ready to send                }
  207.   cOut1              = $04;         { Out 1 - not used in PCs      }
  208.  
  209.   cOut2              = $08;         { Out 2 -                      }
  210.   cMasterEnableInts  = $08;         {   master enables interrupts  }
  211.  
  212.   cLoop              = $10;         { Loop enable (for testing)    }
  213.  
  214.  
  215.   {----------------------------------}
  216.   { Line Status Register (LSR) Flags }
  217.   {----------------------------------}
  218.  
  219.   cDataInRcvBuff     = $01;         { data in receive buffer       }
  220.   cOverrunError      = $02;         { overrrun error               }
  221.   cParityError       = $04;         { parity error                 }
  222.   cFramingError      = $08;         { framing error                }
  223.   cIncomingBreak     = $10;         { incoming break detected      }
  224.   cTHREmpty          = $20;         { Transmit holding reg is empty}
  225.   cTSREmpty          = $40;         { Transmit shift   reg is empty}
  226.   cFIFORcvError      = $80;         { 16550 Fifo receive error     }
  227.  
  228.   {-----------------------------------}
  229.   { Modem Status Register (MSR) Flags }
  230.   {-----------------------------------}
  231.  
  232.   cdCTS      = $01;                 { delta-clear to send          }
  233.   cdDSR      = $02;                 { delta-Data Set Ready         }
  234.   cdRI       = $04;                 { delta-Ring                   }
  235.   cdDCD      = $08;                 { delta-Data Carrier Detect    }
  236.   cCTS       = $10;                 { Clear to send                }
  237.   cDSR       = $20;                 { Data Set Ready               }
  238.   cRI        = $40;                 { Ring Indicator               }
  239.   cDCD       = $80;                 { Data Carrier Detect          }
  240.  
  241.  
  242.  
  243. Type
  244.  
  245.   TPortSettings = RECORD
  246.  
  247.      BasePort : WORD;
  248.      IRQ      : BYTE;
  249.  
  250.   END;
  251.  
  252.   PPortSettings = ^TPortSettings;
  253.  
  254.   TUartInBuffer = Array[0..cInBuffMax] of BYTE;
  255.  
  256.   PUartInBuffer = ^TUartInBuffer;
  257.  
  258.  
  259. Const
  260.  
  261.   PortSettings  : Array[0..cMaxComPort] of TPortSettings=
  262.                     ( (BasePort : $3F8; IRQ : 4),
  263.                       (BasePort : $2F8; IRQ : 3),
  264.                       (BasePort : $3E8; IRQ : 4),
  265.                       (BasePort : $2E8; IRQ : 3),
  266.                       (BasePort : $000; IRQ : 0),
  267.                       (BasePort : $000; IRQ : 0),
  268.                       (BasePort : $000; IRQ : 0),
  269.                       (BasePort : $000; IRQ : 0) );
  270.  
  271. Var
  272.  
  273.   ExitSave         : POINTER;
  274.   OriginalVector   : POINTER;
  275.  
  276.   UartIsOpen       : BOOLEAN;
  277.   Overflow         : BOOLEAN;
  278.  
  279.   Base             : WORD;        { current baseport                  }
  280.   IRQ              : BYTE;        { current IRQ                       }
  281.  
  282.   Buffer           : TUartInBuffer;
  283.  
  284.   BufferHead       : WORD;
  285.   BufferTail       : WORD;
  286.  
  287.   SaveIER          : BYTE;
  288.   SaveMCR          : BYTE;
  289.   SaveLCr          : BYTE;
  290.  
  291.   CtsRtsOn         : Boolean;
  292.  
  293. {────────────────────────────────────────────────────────────────────────────}
  294.  
  295.  
  296. (*-
  297.  
  298. [FUNCTION]
  299.  
  300. Procedure VUartBaudSet(           BaudRate       : LONGINT );
  301.  
  302. [PARAMETERS]
  303.  
  304. baudrate    new baud rate to use
  305.  
  306. [RETURNS]
  307.  
  308. nothing.
  309.  
  310. [DESCRIPTION]
  311.  
  312. This function will set the baud rate of the UART to the specified
  313. value.
  314.  
  315. THIS FUNCTION IS NOT YET IMPLEMENTED!
  316.  
  317. [SEE-ALSO]
  318.  
  319. [EXAMPLE]
  320.  
  321.   VUartBaudSet( 19200 );
  322.  
  323. -*)
  324.  
  325.  
  326. Procedure VUartBaudSet(           BaudRate       : LONGINT );
  327.  
  328. BEGIN
  329.  
  330. END;
  331.  
  332. {────────────────────────────────────────────────────────────────────────────}
  333.  
  334.  
  335. (*-
  336.  
  337. [FUNCTION]
  338.  
  339. Function  VUartBaudGet                                          : LONGINT;
  340.  
  341. [PARAMETERS]
  342.  
  343. none.
  344.  
  345. [RETURNS]
  346.  
  347. current Baud rate of the UART.
  348.  
  349. [DESCRIPTION]
  350.  
  351. This function will get the current baud rate of the UART.
  352.  
  353. [SEE-ALSO]
  354.  
  355. [EXAMPLE]
  356.  
  357.   WriteLn(' Baud Rate = ', VUartBaudGet );
  358.  
  359. -*)
  360.  
  361.  
  362. Function  VUartBaudGet                                          : LONGINT;
  363.  
  364. Var
  365.  
  366.   SaveLCR : WORD;
  367.   BRD     : WORD;
  368.  
  369. BEGIN
  370.  
  371.   {-------------------------------------}
  372.   { get the line control register value }
  373.   {-------------------------------------}
  374.  
  375.   SaveLCR := Port[ cUartLCR + Base ];
  376.  
  377.   {----------------------------------}
  378.   { set the access divsor latch flag }
  379.   {----------------------------------}
  380.  
  381.   Port[ cUartLCR + Base ] := SaveLCR OR cAccessDivLatch;
  382.  
  383.   {-------------------------------------------------------------}
  384.   { The THR and IER regs are now the Baud Rate Divisor register }
  385.   { so we get the baud rate divisor                             }
  386.   {-------------------------------------------------------------}
  387.  
  388.   TCastWord( BRD ).LowByte  := Port[ cUartTHR + Base ];
  389.   TCastWord( BRD ).HighByte := Port[ cUartIER + Base ];
  390.  
  391.   {--------------------------------------------------------------}
  392.   { clear the access divisor latch / set LCR back to what it was }
  393.   {--------------------------------------------------------------}
  394.  
  395.   Port[ cUartLCR + Base ] := SaveLCR;
  396.  
  397.   {-------------------------------------------------}
  398.   { divide the input clock by the baud rate divisor }
  399.   { to get the baud rate                            }
  400.   {-------------------------------------------------}
  401.  
  402.   VUartBaudGet := cUartClockFreq DIV BRD;
  403.  
  404. END;
  405.  
  406. {────────────────────────────────────────────────────────────────────────────}
  407.  
  408.  
  409. (*-
  410.  
  411. [FUNCTION]
  412.  
  413. Function  VUartLSRGet : BYTE;
  414.  
  415. [PARAMETERS]
  416.  
  417. None.
  418.  
  419. [RETURNS]
  420.  
  421. Line Status Register.
  422.  
  423. [DESCRIPTION]
  424.  
  425. This function will get the line-status register of the UART.
  426.  
  427.   Line status register flags
  428.   --------------------------
  429.  
  430.   cDataInRcvBuff     = $01;         { data in receive buffer       }
  431.   cOverrunError      = $02;         { overrrun error               }
  432.   cParityError       = $04;         { parity error                 }
  433.   cFramingError      = $08;         { framing error                }
  434.   cIncomingBreak     = $10;         { incoming break detected      }
  435.   cTHREmpty          = $20;         { Transmit holding reg is empty}
  436.   cTSREmpty          = $40;         { Transmit shift   reg is empty}
  437.   cFIFORcvError      = $80;         { 16550 Fifo receive error     }
  438.  
  439. [SEE-ALSO]
  440.  
  441. [EXAMPLE]
  442.  
  443.   If (VUartLSRGet AND cParityError)>0 Then
  444.     WriteLn('Parity error!')
  445.   Else
  446.     WriteLn('No parity error.');
  447.  
  448. -*)
  449.  
  450.  
  451. Function  VUartLSRGet : BYTE;
  452.  
  453. BEGIN
  454.  
  455.   VUartLSRGet := (Port[ Base+cUartLSR ]);
  456.  
  457. END;
  458.  
  459. {────────────────────────────────────────────────────────────────────────────}
  460.  
  461. (*-
  462.  
  463. [FUNCTION]
  464.  
  465.  
  466. Function  VUartMSRGet : BYTE;
  467.  
  468. [PARAMETERS]
  469.  
  470. None.
  471.  
  472. [RETURNS]
  473.  
  474. Modem Status Register.
  475.  
  476. [DESCRIPTION]
  477.  
  478. This function will get the modem-status register of the UART.
  479.  
  480.   Modem status register flags
  481.   ---------------------------
  482.  
  483.   cdCTS      = $01;                 { delta-clear to send          }
  484.   cdDSR      = $02;                 { delta-Data Set Ready         }
  485.   cdRI       = $04;                 { delta-Ring                   }
  486.   cdDCD      = $08;                 { delta-Data Carrier Detect    }
  487.   cCTS       = $10;                 { Clear to send                }
  488.   cDSR       = $20;                 { Data Set Ready               }
  489.   cRI        = $40;                 { Ring Indicator               }
  490.   cDCD       = $80;                 { Data Carrier Detect          }
  491.  
  492.  
  493.  
  494. [SEE-ALSO]
  495.  
  496. [EXAMPLE]
  497.  
  498.   If (VUartMSRGet AND cCTS)>0 Then
  499.     WriteLn('Clear to send!')
  500.   Else
  501.     WriteLn('cant send yet....');
  502.  
  503. -*)
  504.  
  505.  
  506.  
  507. Function  VUartMSRGet : BYTE;
  508.  
  509. BEGIN
  510.  
  511.   VUartMSRGet := (Port[ Base+cUartMSR ]);
  512.  
  513. END;
  514.  
  515. {────────────────────────────────────────────────────────────────────────────}
  516.  
  517. (*-
  518.  
  519. [FUNCTION]
  520.  
  521.  
  522. Function  VUartLCRGet : BYTE;
  523.  
  524. [PARAMETERS]
  525.  
  526. None.
  527.  
  528. [RETURNS]
  529.  
  530. Line control Register.
  531.  
  532. [DESCRIPTION]
  533.  
  534. This function will get the line-control register of the UART.
  535.  
  536.   Line-Control register flags
  537.   ---------------------------
  538.  
  539.   cDataBitsMask      = $01+$02;     { Data bits (wordsize) mask    }
  540.   cDataBits5         = $00;         { Data bits = 5                }
  541.   cDataBits6         = $01;         { Data bits = 6                }
  542.   cDataBits7         = $02;         { Data bits = 7                }
  543.   cDataBits8         = $01+$02;     { Data bits = 8                }
  544.  
  545.   cStopBits1         = $00;         { Stop bits = 1                }
  546.   cStopBits2         = $04;         { Stop bits = 2                }
  547.  
  548.   cParityEnable      = $08;         { Enable parity                }
  549.  
  550.   cParityEven        = $10;         { even parity                  }
  551.  
  552.   cStickyParity      = $20;         { sticky parity                }
  553.  
  554.   cBreakOn           = $40;         { turn break on                }
  555.  
  556.   cAccessDivLatch    = $80;         { access divisor latch         }
  557.  
  558.  
  559. [SEE-ALSO]
  560.  
  561. [EXAMPLE]
  562.  
  563. -*)
  564.  
  565.  
  566. Function  VUartLCRGet : BYTE;
  567.  
  568. BEGIN
  569.  
  570.   VUartLCRGet := (Port[ Base+cUartLCR ]);
  571.  
  572. END;
  573.  
  574. {────────────────────────────────────────────────────────────────────────────}
  575.  
  576. (*-
  577.  
  578. [FUNCTION]
  579.  
  580.  
  581. Function  VUartMCRGet : BYTE;
  582.  
  583. [PARAMETERS]
  584.  
  585. None.
  586.  
  587. [RETURNS]
  588.  
  589. Line control Register.
  590.  
  591. [DESCRIPTION]
  592.  
  593. This function will get the modem-control register of the UART.
  594.  
  595.   modem-Control register flags
  596.   ----------------------------
  597.  
  598.   cDTR               = $01;         { Data terminal ready          }
  599.   cRTS               = $02;         { Ready to send                }
  600.   cOut1              = $04;         { Out 1 - not used in PCs      }
  601.  
  602.   cOut2              = $08;         { Out 2 -                      }
  603.   cMasterEnableInts  = $08;         {   master enables interrupts  }
  604.  
  605.   cLoop              = $10;         { Loop enable (for testing)    }
  606.  
  607.  
  608. [SEE-ALSO]
  609.  
  610. [EXAMPLE]
  611.  
  612. -*)
  613.  
  614.  
  615.  
  616.  
  617. Function  VUartMCRGet : BYTE;
  618.  
  619. BEGIN
  620.  
  621.   VUartMCRGet := (Port[ Base+cUartMCR ]);
  622.  
  623. END;
  624.  
  625. {────────────────────────────────────────────────────────────────────────────}
  626.  
  627.  
  628. (*-
  629.  
  630. [FUNCTION]
  631.  
  632. Function  VUartIsCarrier : BOOLEAN;
  633.  
  634. [PARAMETERS]
  635.  
  636. None.
  637.  
  638. [RETURNS]
  639.  
  640. TRUE if a carrier is present,
  641. FALSE if a carrier is NOT present.
  642.  
  643. [DESCRIPTION]
  644.  
  645. This function will return TRUE if a data carrier is present.
  646.  
  647. [SEE-ALSO]
  648.  
  649. [EXAMPLE]
  650.  
  651. -*)
  652.  
  653. Function  VUartIsCarrier : BOOLEAN;
  654.  
  655. BEGIN
  656.  
  657.   VUartISCarrier := (Port[ CUartMSR + Base ] AND cDCD)>0;
  658.  
  659. END;
  660.  
  661. {────────────────────────────────────────────────────────────────────────────}
  662.  
  663.  
  664.  
  665. (*-
  666.  
  667. [FUNCTION]
  668.  
  669. Procedure CommIsr; Interrupt;
  670.  
  671. [PARAMETERS]
  672.  
  673. None.
  674.  
  675. [RETURNS]
  676.  
  677. Nothing.
  678.  
  679. [DESCRIPTION]
  680.  
  681. This procedure is the VUartU s internal interrupt service routine.
  682. It should NOT be called externally.  This interrupt is called any time the
  683. UART receives a character.
  684.  
  685. [SEE-ALSO]
  686.  
  687. [EXAMPLE]
  688.  
  689. -*)
  690.  
  691.  
  692. Procedure CommIsr; Interrupt;
  693.  
  694. BEGIN
  695.  
  696.   ASM
  697.  
  698.     { get the incoming character from the UART }
  699.     { and put it into our incoming char buffer }
  700.  
  701.     @@GetTheChar:
  702.  
  703.       STI
  704.  
  705.       MOV DX, Base
  706.       IN  AL, DX
  707.       MOV BX, BufferHead
  708.       MOV byte PTR Buffer[BX], AL
  709.  
  710.       INC BX
  711.  
  712.     { check to see if we are at the end of the buffer }
  713.  
  714.     @@CheckAtEnd:
  715.       CMP BX, cInBuffMax
  716.       JLE @@CheckOver
  717.       XOR BX, BX
  718.  
  719.     { check to see if an overflow occurred (head=tail) }
  720.  
  721.     @@CheckOver:
  722.       CMP BX, BufferTail
  723.       JNE @@CheckNextChar
  724.       MOV Overflow,1
  725.       JMP @@AllDone
  726.  
  727.     { check to see if more characters are waiting }
  728.  
  729.     @@CheckNextchar:
  730.       MOV Bufferhead, BX
  731.       ADD DX,5
  732.       IN  AL,DX
  733.  
  734.       AND AL, $01
  735.       CMP AL, $01
  736.       JE  @@GetTheChar
  737.  
  738.     { clean up and leave }
  739.  
  740.     @@AllDone:
  741.       CLI
  742.       MOV AL,20h
  743.       OUT 20h, AL
  744.  
  745.   END;
  746.  
  747. END; { CommIsr }
  748.  
  749. {────────────────────────────────────────────────────────────────────────────}
  750.  
  751.  
  752.  
  753. (*-
  754.  
  755. [FUNCTION]
  756.  
  757. Procedure VUartClose;
  758.  
  759. [PARAMETERS]
  760.  
  761. None.
  762.  
  763. [RETURNS]
  764.  
  765. Nothing.
  766.  
  767. [DESCRIPTION]
  768.  
  769. This function is used internally.
  770.  
  771. [SEE-ALSO]
  772.  
  773. [EXAMPLE]
  774.  
  775. -*)
  776.  
  777. Procedure VUartClose;
  778.  
  779. BEGIN
  780.  
  781.   If UartIsOpen Then
  782.   BEGIN
  783.  
  784.     { begin critical code }
  785.  
  786.     ASM CLI; END;
  787.  
  788.     { turn off our int in the 8259 IRQ mask register }
  789.  
  790.     Port[ cIntMaskReg ] := ( Port[ cIntMaskReg ] or (1 SHL IRQ) );
  791.  
  792.     { restore the saved UART registers }
  793.  
  794.     Port[ Base + cUartIER ] := SaveIER;
  795.  
  796.     Port[ Base + cUartMCR ] := SaveMCR;
  797.  
  798.     Port[ Base + cUartLCR ] := SaveLCR;
  799.  
  800.     { restore the orignal interrupt vector }
  801.  
  802.     SetIntVec( IRQ+8, OriginalVector );
  803.  
  804.     { end of critical code }
  805.  
  806.     ASM STI; END;
  807.  
  808.     UartIsOpen := FALSE;
  809.  
  810.   END;
  811.  
  812. END;
  813.  
  814. {────────────────────────────────────────────────────────────────────────────}
  815.  
  816.  
  817. (*-
  818.  
  819. [FUNCTION]
  820.  
  821. Function  VUartOpen(              ComPort        : BYTE;
  822.                                   BaudRate       : LONGINT     ):BOOLEAN;
  823.  
  824. [PARAMETERS]
  825.  
  826. comport     comport to open (1-4)
  827. baudrate    baudrate to use
  828.  
  829. [RETURNS]
  830.  
  831. TRUE if the open was successfull,
  832. FALSE if the open was not.
  833.  
  834. [DESCRIPTION]
  835.  
  836. This function is used internally.
  837.  
  838. [SEE-ALSO]
  839.  
  840. [EXAMPLE]
  841.  
  842. -*)
  843.  
  844.  
  845. Function  VUartOpen(              ComPort        : BYTE;
  846.                                   BaudRate       : LONGINT     ):BOOLEAN;
  847.  
  848. Var
  849.  
  850.   SaveIIR    : BYTE;
  851.   Is16550    : BOOLEAN;
  852.   PortGood   : BOOLEAN;
  853.  
  854. BEGIN
  855.  
  856.   { set the buffer head and tail to nada }
  857.  
  858.   BufferHead       := 0;
  859.   BufferTail       := 0;
  860.  
  861.   { clear overflow and uartisopen flag }
  862.  
  863.   Overflow         := FALSE;
  864.  
  865.   UartIsOpen       := FALSE;
  866.  
  867.   { do we know the baseport for this com-port? }
  868.  
  869.   If PortSettings[ Pred( ComPort ) ].BasePort <>0 Then
  870.   BEGIN
  871.  
  872.     { get out baseport and irq }
  873.  
  874.     Base    := PortSettings[ Pred( ComPort ) ].BasePort;
  875.     IRQ     := PortSettings[ Pred( ComPort ) ].IRQ;
  876.  
  877.     { save various UART regs }
  878.  
  879.     SaveIER := Port[ Base + cUartIER ];
  880.     SaveMCR := Port[ Base + cUartMCR ];
  881.     SaveLCR := Port[ Base + cUartLCR ];
  882.  
  883.     { check for the port }
  884.  
  885.     Port[ Base+CUartLCR ] := $75;
  886.  
  887.     PortGood := (Port[ Base + CUartLCR ]=$75);
  888.  
  889.     { set port to n,8,1 }
  890.  
  891.     Port[ Base+cUartLCR ] := cDataBits8;
  892.  
  893.  
  894.     If PortGood Then
  895.     BEGIN
  896.  
  897.       { set the baud }
  898.  
  899.       VUartBaudSet( BaudRate );
  900.  
  901.       { turn on master ints, and set RTS and DTR }
  902.  
  903.       Port[ Base + CUartMCR ] := cMasterEnableInts + cRTS + cDTR;
  904.  
  905.       { save the interrupt ID register }
  906.  
  907.       SaveIIR := Port[ Base + cUartIIR ];
  908.  
  909.       { try to enable the fifos }
  910.  
  911.       Port[ Base + cUartIIR ] := 1;
  912.  
  913.       { did the Fifo mode status flags show up? }
  914.  
  915.       Is16550 := ( ( Port[ Base + cUartIIR ] AND
  916.                       cFifoModeMask              ) = cFifoModeFifo );
  917.  
  918.       { if they didnt, set IIR back to what it was }
  919.  
  920.       If Is16550=FALSE Then
  921.         Port[ Base + CUartIIR ] := SaveIIR;
  922.  
  923.       { save the original IRQ vector off }
  924.  
  925.       GetIntVec( IRQ+8, OriginalVector );
  926.  
  927.       { setup our IRQ vector }
  928.  
  929.       SetIntVec( IRQ+8, @CommIsr           );
  930.  
  931.       { beginning of critical code }
  932.  
  933.       ASM CLI; END;
  934.  
  935.       { enable our IRQ in the 8259 IRQ mask register }
  936.  
  937.       Port[ cIntMaskReg ] := Port[ cIntMaskReg ] AND
  938.                                 ( (1 SHL IRQ) XOR $FF );
  939.  
  940.       { enable the 8250s receive interrupt }
  941.  
  942.       Port[ Base + cUartIER ] := cEnableRcvInt;
  943.  
  944.       { end or critical code }
  945.  
  946.       ASM STI; END;
  947.  
  948.       UartIsOpen := TRUE;
  949.  
  950.     END; { if portthere }
  951.  
  952.   END; { if we found a base port in the settings table }
  953.  
  954.   VUartOpen := UartIsOpen;
  955.  
  956. END;
  957.  
  958. {────────────────────────────────────────────────────────────────────────────}
  959.  
  960.  
  961. Procedure ExitUnit; Far;
  962.  
  963. BEGIN
  964.  
  965.   VUartClose;
  966.  
  967.   ExitProc := ExitSave;
  968.  
  969. END;
  970.  
  971.  
  972. {────────────────────────────────────────────────────────────────────────────}
  973.  
  974.  
  975.  
  976. (*-
  977.  
  978. [FUNCTION]
  979.  
  980. Function  VUartInit(              ComPort        : BYTE;
  981.                                   BaudRate       : LONGINT     ): WORD;
  982.  
  983. [PARAMETERS]
  984.  
  985. comport     comport to open (1-4)
  986. baudrate    baudrate to use
  987.  
  988. [RETURNS]
  989.  
  990. TRUE if the open was successfull,
  991. FALSE if the open was not.
  992.  
  993. [DESCRIPTION]
  994.  
  995. This function should be called before the other VUart functions are
  996. used.  "Comport" should be the comport (1-4) that you wish to use.
  997. "baudrate" is the baud rate you would like the comport to be opened
  998. at.  This function initializes the UART and sets up the Vuart
  999. interrupt service routine to service incoming characters.
  1000.  
  1001. [SEE-ALSO]
  1002.  
  1003. [EXAMPLE]
  1004.  
  1005. -*)
  1006.  
  1007. Function  VUartInit(              ComPort        : BYTE;
  1008.                                   BaudRate       : LONGINT     ): WORD;
  1009.  
  1010. BEGIN
  1011.  
  1012.   If Not UartIsOpen Then
  1013.   BEGIN
  1014.  
  1015.  
  1016.     If VUartOpen( ComPort, BaudRate ) Then
  1017.       VUartInit   := 0
  1018.     ELSE
  1019.       VUartInit := 1;
  1020.  
  1021.   END; { if not UartIsOpen }
  1022.  
  1023. END; { VUartInit }
  1024.  
  1025. {────────────────────────────────────────────────────────────────────────────}
  1026.  
  1027.  
  1028. (*-
  1029.  
  1030. [FUNCTION]
  1031.  
  1032. Function  VUartIsRXReady : BOOLEAN;
  1033.  
  1034. [PARAMETERS]
  1035.  
  1036. None.
  1037.  
  1038. [RETURNS]
  1039.  
  1040. TRUE if characters are available to be read from the receive buffer,
  1041. FALSE if no characters are available.
  1042.  
  1043. [DESCRIPTION]
  1044.  
  1045. This function reports on the condition of the receiver buffer.  It
  1046. will return TRUE if characters are available, and FALSE if characters
  1047. are not available.
  1048.  
  1049. [SEE-ALSO]
  1050.  
  1051. [EXAMPLE]
  1052.  
  1053. -*)
  1054.  
  1055. Function  VUartIsRXReady : BOOLEAN;
  1056.  
  1057. BEGIN
  1058.   VUartIsRXReady := (BufferHead<>BufferTail);
  1059. END;
  1060.  
  1061. {────────────────────────────────────────────────────────────────────────────}
  1062.  
  1063.  
  1064. (*-
  1065.  
  1066. [FUNCTION]
  1067.  
  1068. Procedure VUartDeInit;
  1069.  
  1070. [PARAMETERS]
  1071.  
  1072. None.
  1073.  
  1074. [RETURNS]
  1075.  
  1076. Nothing.
  1077.  
  1078. [DESCRIPTION]
  1079.  
  1080. This procedure should be called when your program is done with the
  1081. UART.  This function disposes of any dynamically memory that was
  1082. allocated by VUartOpen and restores the UART back to the state
  1083. it was in when open called.  This function also restores the
  1084. UARTS interrupt service routine back to what it previously was.
  1085.  
  1086. [SEE-ALSO]
  1087.  
  1088. [EXAMPLE]
  1089.  
  1090. -*)
  1091.  
  1092. Procedure VUartDeInit;
  1093.  
  1094. BEGIN
  1095.  
  1096.   VUartClose;
  1097.  
  1098. END;
  1099.  
  1100. {────────────────────────────────────────────────────────────────────────────}
  1101.  
  1102.  
  1103. (*-
  1104.  
  1105. [FUNCTION]
  1106.  
  1107. Function VUartReadChar : CHAR;
  1108.  
  1109. [PARAMETERS]
  1110.  
  1111. None.
  1112.  
  1113. [RETURNS]
  1114.  
  1115. The new character.
  1116.  
  1117. [DESCRIPTION]
  1118.  
  1119. This function reads the next available character from the receive buffer.
  1120. If no characters are available, it waits until a character is received,
  1121. and then returns it.
  1122.  
  1123. [SEE-ALSO]
  1124.  
  1125. [EXAMPLE]
  1126.  
  1127. -*)
  1128.  
  1129. Function VUartReadChar : CHAR;
  1130.  
  1131. BEGIN
  1132.  
  1133.   { wait till something is in the buffer }
  1134.  
  1135.   While BufferTail=BufferHead DO;
  1136.  
  1137.   { read a character }
  1138.  
  1139.   VUartReadChar := char( Buffer[ BufferTail ] );
  1140.  
  1141.   { move the tail }
  1142.  
  1143.   BufferTail  := ( Succ( BufferTail ) MOD cInBuffSize );
  1144.  
  1145. END;
  1146.  
  1147. {────────────────────────────────────────────────────────────────────────────}
  1148.  
  1149.  
  1150. (*-
  1151.  
  1152. [FUNCTION]
  1153.  
  1154. Function  VUartIsTXReady : BOOLEAN;
  1155.  
  1156. [PARAMETERS]
  1157.  
  1158. None.
  1159.  
  1160. [RETURNS]
  1161.  
  1162. TRUE if the UART is ready to write another character,
  1163. FALSE if it is not.
  1164.  
  1165. [DESCRIPTION]
  1166.  
  1167. This function returns TRUE if the UART is currently ready to send
  1168. out another character, and FALSE if it is not.
  1169.  
  1170. [SEE-ALSO]
  1171.  
  1172. [EXAMPLE]
  1173.  
  1174. -*)
  1175.  
  1176. Function VUartIsTXready : BOOLEAN;
  1177.  
  1178. Var
  1179.  
  1180.   THR   : BOOLEAN;
  1181.   CTS   : BOOLEAN;
  1182.   Car   : BOOLEAN;
  1183.  
  1184. BEGIN
  1185.  
  1186.   { check THR, CTS, and CAR }
  1187.  
  1188.   THR := ( (Port[ Base+cUartLSR ] and cTHREmpty) >0 );
  1189.   CTS := ( (Port[ Base+cUartMSR ] and cCTS     ) >0 );
  1190.   CAR := ( (Port[ Base+CUartMSR ] and cDCD     ) >0 );
  1191.  
  1192.   { if cts/rts is on and their is a carrier ... }
  1193.  
  1194.   If CtsRtsOn and CAR Then
  1195.     VUartIsTXReady := THR AND CTS
  1196.   ELSE
  1197.     VUartIsTXReady := THR;
  1198.  
  1199. END;
  1200.  
  1201. {────────────────────────────────────────────────────────────────────────────}
  1202.  
  1203. (*-
  1204.  
  1205. [FUNCTION]
  1206.  
  1207. Procedure VUartWriteChar(         Ch             : CHAR );
  1208.  
  1209. [PARAMETERS]
  1210.  
  1211. ch          character to write.
  1212.  
  1213. [RETURNS]
  1214.  
  1215. [DESCRIPTION]
  1216.  
  1217.  
  1218. This function writes a charcter to the UART.  Before using this
  1219. function, you should first check to make sure the UART is ready to
  1220. send another character.
  1221.  
  1222. [SEE-ALSO]
  1223.  
  1224. [EXAMPLE]
  1225.  
  1226. -*)
  1227.  
  1228.  
  1229. Procedure VUartWriteChar(         Ch             : CHAR );
  1230.  
  1231. BEGIN
  1232.  
  1233.   { wait until output is ready }
  1234.  
  1235.   While Not VUartIsTXReady DO;
  1236.  
  1237.   { send the char }
  1238.  
  1239.   Port[ Base+cUartTHR ] := Byte(Ch);
  1240.  
  1241. END;
  1242.  
  1243.  
  1244. {────────────────────────────────────────────────────────────────────────────}
  1245.  
  1246. (*-
  1247.  
  1248. [FUNCTION]
  1249.  
  1250. Procedure VUartOutFlush;
  1251.  
  1252. [PARAMETERS]
  1253.  
  1254. [RETURNS]
  1255.  
  1256. [DESCRIPTION]
  1257.  
  1258. This function insures that any characters which are buffered
  1259. and have not yet been sent are sent.
  1260.  
  1261. [SEE-ALSO]
  1262.  
  1263. [EXAMPLE]
  1264.  
  1265. -*)
  1266.  
  1267. Procedure VUartOutFlush;
  1268.  
  1269. BEGIN
  1270.  
  1271.   { flush 16550 fifos }
  1272.  
  1273. END;
  1274.  
  1275. {────────────────────────────────────────────────────────────────────────────}
  1276.  
  1277. (*-
  1278.  
  1279. [FUNCTION]
  1280.  
  1281. Procedure VUartOutPurge;
  1282.  
  1283. [PARAMETERS]
  1284.  
  1285. [RETURNS]
  1286.  
  1287. [DESCRIPTION]
  1288.  
  1289. This function purges any characters which are in the transmit buffer.
  1290. Since UART currently does not implement a transmit buffer, this function
  1291. doesn't do anything.
  1292.  
  1293. [SEE-ALSO]
  1294.  
  1295. [EXAMPLE]
  1296.  
  1297. -*)
  1298.  
  1299.  
  1300. Procedure VUartOutPurge;
  1301.  
  1302. BEGIN
  1303.  
  1304.   { Purge 16550 fifos }
  1305.  
  1306. END;
  1307.  
  1308. {────────────────────────────────────────────────────────────────────────────}
  1309.  
  1310. (*-
  1311.  
  1312. [FUNCTION]
  1313.  
  1314. Procedure VUartInPurge;
  1315.  
  1316. [PARAMETERS]
  1317.  
  1318. [RETURNS]
  1319.  
  1320. [DESCRIPTION]
  1321.  
  1322. This function purges any characters that are in the receive buffer.
  1323.  
  1324. [SEE-ALSO]
  1325.  
  1326. [EXAMPLE]
  1327.  
  1328. -*)
  1329.  
  1330. Procedure VUartInPurge;
  1331.  
  1332. BEGIN
  1333.   BufferHead := 0;
  1334.   BufferTail := 0;
  1335.   OverFlow   := FALSE;
  1336. END;
  1337.  
  1338. {────────────────────────────────────────────────────────────────────────────}
  1339.  
  1340.  
  1341. (*-
  1342.  
  1343. [FUNCTION]
  1344.  
  1345. Procedure VUartBreak(             DelayMS        : WORD         );
  1346.  
  1347. [PARAMETERS]
  1348.  
  1349. delayms     count of milliseconds to break for.
  1350.  
  1351. [RETURNS]
  1352.  
  1353. [DESCRIPTION]
  1354.  
  1355. This function sends a break signal for the specified "delayMS".
  1356.  
  1357. [SEE-ALSO]
  1358.  
  1359. [EXAMPLE]
  1360.  
  1361. -*)
  1362.  
  1363. Procedure VUartBreak(             DelayMS        : WORD         );
  1364.  
  1365. Var
  1366.   LCR : BYTE;
  1367.  
  1368. BEGIN
  1369.  
  1370.   { get the current LCR }
  1371.  
  1372.   LCR := Port[ Base+cUartLCR ];
  1373.  
  1374.   { put it back with BREAK ON set }
  1375.  
  1376.   Port[ Base+cUartLCR ] := ( (LCR AND $7F) OR cBreakOn );
  1377.  
  1378.   { delay... }
  1379.  
  1380.   { Delay( DelayMS ); }
  1381.  
  1382.   { set LCR back to what it was }
  1383.  
  1384.   Port[ Base+cUartLCR ] := LCR;
  1385.  
  1386. END;
  1387.  
  1388. {────────────────────────────────────────────────────────────────────────────}
  1389.  
  1390. (*-
  1391.  
  1392. [FUNCTION]
  1393.  
  1394. Procedure VUartDTROn;
  1395.  
  1396. [PARAMETERS]
  1397.  
  1398. [RETURNS]
  1399.  
  1400. [DESCRIPTION]
  1401.  
  1402. This function turns DTR (Data Terminal Ready) on.
  1403.  
  1404. [SEE-ALSO]
  1405.  
  1406. [EXAMPLE]
  1407.  
  1408. -*)
  1409.  
  1410.  
  1411. Procedure VUartDTROn;
  1412.  
  1413. BEGIN
  1414.  
  1415.   Port[ Base+cUartMCR ] := cMasterEnableInts + cRTS + cDTR;
  1416.  
  1417. END;
  1418.  
  1419. {────────────────────────────────────────────────────────────────────────────}
  1420.  
  1421. Procedure VUartDTROff;
  1422.  
  1423. BEGIN
  1424.  
  1425.   Port[ Base+cUartMCR ] := cMasterEnableInts + cRTS;
  1426.  
  1427. END;
  1428.  
  1429.  
  1430. {────────────────────────────────────────────────────────────────────────────}
  1431.  
  1432. Procedure VUartCtsRtsSet(         ON             : BOOLEAN );
  1433.  
  1434. BEGIN
  1435.   CtsRtsOn := ON;
  1436. END;
  1437.  
  1438. {────────────────────────────────────────────────────────────────────────────}
  1439.  
  1440. Procedure VUartWriteBlock(        Block          : POINTER;
  1441.                                   Count          : WORD         );
  1442.  
  1443. Var
  1444.   Z : INTEGER;
  1445.  
  1446. BEGIN
  1447.  
  1448.   For Z := 1 to Count Do
  1449.     VUartWriteChar( PCharArray( Block )^[Z] );
  1450.  
  1451. END;
  1452.  
  1453. {────────────────────────────────────────────────────────────────────────────}
  1454.  
  1455.  
  1456. Procedure VUartReadBlock(         Block          : POINTER;
  1457.                                   Count          : WORD         );
  1458.  
  1459. Var
  1460.   Z : INTEGER;
  1461.  
  1462. BEGIN
  1463.  
  1464.   For Z := 1 to Count Do
  1465.     PCharArray( Block )^[Z] := VUartReadChar;
  1466.  
  1467. END;
  1468.  
  1469. {────────────────────────────────────────────────────────────────────────────}
  1470.  
  1471.  
  1472. Procedure UartSerDriverProc( SDP : PSerDriverPacket );
  1473.  
  1474. Type
  1475.  
  1476.   TUartIData = RECORD
  1477.  
  1478.     ComPort   : BYTE;      { Communications port                        }
  1479.     BaudRate  : LONGINT;   { Bits per second rate                       }
  1480.     Parity    : CHAR;      { Parity of hardware error checking          }
  1481.     DataBits  : BYTE;      { Number of data bits                        }
  1482.     StopBits  : BYTE;      { Number of stop bits                        }
  1483.     PortStat  : WORD;      { Condition of UART. LoByte=MSR,HiByte=LSR   }
  1484.  
  1485.   END;
  1486.  
  1487.   PUartIdata = ^TUartIdata;
  1488.  
  1489. Var
  1490.  
  1491.   IData : PUartIData;
  1492.  
  1493. BEGIN
  1494.  
  1495.   IData := SDP^.IData;
  1496.  
  1497.   If SDP^.Status = 0 Then
  1498.   BEGIN
  1499.  
  1500.     Case SDP^.Func of
  1501.  
  1502.       {--------}
  1503.  
  1504.       SDFDriverNew:
  1505.       BEGIN
  1506.  
  1507.         IF @SDP^.SerDriverProc = @UartSerDriverProc Then
  1508.         BEGIN
  1509.  
  1510.           New( IData );
  1511.  
  1512.           FillChar( IData^, SizeOf( TUartIData), 0 );
  1513.  
  1514.           {--------------------------}
  1515.           { build instance data here }
  1516.           {--------------------------}
  1517.  
  1518.           IData^.ComPort := Pred( SDP^.DriverInfo1 );
  1519.  
  1520.           {--------------------------}
  1521.  
  1522.           SDP^.IData := IData;
  1523.  
  1524.           SDP^.Error := 0;
  1525.  
  1526.         END;
  1527.  
  1528.       END; { Case SDF_DriverNew }
  1529.  
  1530.       {--------}
  1531.  
  1532.       SDFDriverOff:
  1533.       BEGIN
  1534.       END;
  1535.  
  1536.       {--------}
  1537.  
  1538.       SDFDriverOn:
  1539.       BEGIN
  1540.       END;
  1541.  
  1542.       {--------}
  1543.  
  1544.       SDFDriverDispose:
  1545.       BEGIN
  1546.  
  1547.         {--------------------------------}
  1548.         { Resolve any instance data here }
  1549.         {--------------------------------}
  1550.  
  1551.  
  1552.         {---------------------------}
  1553.         { Dispose all instance data }
  1554.         {---------------------------}
  1555.  
  1556.         If SDP^.IData <> NIL Then
  1557.         BEGIN
  1558.  
  1559.           Dispose( SDP^.IData );
  1560.           SDP^.IData := NIL;
  1561.  
  1562.         END;
  1563.  
  1564.       END;
  1565.  
  1566.       {--------}
  1567.  
  1568.       SDFActivate:
  1569.       BEGIN
  1570.  
  1571.         SDP^.Error := 0;
  1572.  
  1573.         If VUartInit( IData^.ComPort,
  1574.                       SDP^.CommParam^.BaudRate  )=0 Then
  1575.         BEGIN
  1576.  
  1577.  
  1578.           SDP^.Error := 0;
  1579.  
  1580.         END
  1581.         ELSE
  1582.         BEGIN
  1583.  
  1584.           SDP^.Error := $FFFF0000;
  1585.  
  1586.         END;
  1587.  
  1588.       END;
  1589.  
  1590.       {--------}
  1591.  
  1592.       SDFDeActivate:
  1593.       BEGIN
  1594.  
  1595.         VUartDeInit;
  1596.  
  1597.         SDP^.Error := 0;
  1598.  
  1599.       END;
  1600.  
  1601.       {--------}
  1602.  
  1603.       SDFSetCommParam:
  1604.       BEGIN
  1605.  
  1606.         (*
  1607.         IData^.BaudRate := SDP^.CommParam^.BaudRate;
  1608.         IData^.Parity   := SDP^.CommParam^.Parity;
  1609.         IData^.DataBits := SDP^.CommParam^.DataBits;
  1610.         IData^.StopBits := SDP^.CommParam^.StopBits;
  1611.         *)
  1612.  
  1613.         SDP^.Error := 0;
  1614.  
  1615.       END;
  1616.  
  1617.       {--------}
  1618.  
  1619.       SDFGetCommParam:
  1620.       BEGIN
  1621.  
  1622.         SDP^.CommParam^.BaudRate   := VUartBaudGet;
  1623.         SDP^.CommParam^.Parity     := 'N';
  1624.         SDP^.CommParam^.DataBits   := 8;
  1625.         SDP^.CommParam^.StopBits   := 1;
  1626.  
  1627.         SDP^.Error := 0;
  1628.  
  1629.       END;
  1630.  
  1631.       {--------}
  1632.  
  1633.       SDFGetFlowConType:
  1634.       BEGIN
  1635.  
  1636.         SDP^.Error := 0;
  1637.  
  1638.       END;
  1639.  
  1640.       {--------}
  1641.  
  1642.       SDFSetFlowConType:
  1643.       BEGIN
  1644.  
  1645.         SDP^.Error := $FFFF0000;
  1646.  
  1647.       END;
  1648.  
  1649.       {--------}
  1650.  
  1651.       SDFTurnSendOnOff:
  1652.       BEGIN
  1653.  
  1654.         SDP^.Error := $FFFF0000;
  1655.  
  1656.       END;
  1657.  
  1658.       {--------}
  1659.  
  1660.       SDFTurnReceiveOnOff:
  1661.       BEGIN
  1662.  
  1663.         SDP^.Error := $FFFF0000;
  1664.  
  1665.       END;
  1666.  
  1667.  
  1668.       {--------}
  1669.  
  1670.       sdfGetFlowConChars:
  1671.       BEGIN
  1672.  
  1673.         SDP^.Error := $FFFF0000;
  1674.  
  1675.       END;
  1676.  
  1677.       {--------}
  1678.  
  1679.       sdfSetFlowConChars:
  1680.       BEGIN
  1681.  
  1682.         SDP^.Error := $FFFF0000;
  1683.  
  1684.       END;
  1685.  
  1686.       {--------}
  1687.  
  1688.  
  1689.       {--------}
  1690.       {--------}
  1691.  
  1692.       sdfGetLineControl:
  1693.       BEGIN
  1694.  
  1695.         SDP^.Val   := VUartLCRGet;
  1696.         SDP^.Error := 0;
  1697.  
  1698.       END;
  1699.  
  1700.       {--------}
  1701.  
  1702.       sdfGetLineStatus:
  1703.       BEGIN
  1704.  
  1705.         SDP^.Val    := VUartLSRGet;
  1706.         SDP^.Error  := 0;
  1707.  
  1708.       END;
  1709.  
  1710.       {--------}
  1711.  
  1712.       sdfGetModemControl:
  1713.       BEGIN
  1714.  
  1715.         SDP^.Val    := VUartMCRGet;
  1716.         SDP^.Error  := 0;
  1717.  
  1718.       END;
  1719.  
  1720.       {--------}
  1721.  
  1722.       sdfGetModemStatus:
  1723.       BEGIN
  1724.  
  1725.         SDP^.Val    := VUartMSRGet;
  1726.         SDP^.Error  := 0;
  1727.  
  1728.       END;
  1729.  
  1730.       {--------}
  1731.  
  1732.       sdfGetBothStatus:
  1733.       BEGIN
  1734.  
  1735.         { msr in lower, lsr in higher }
  1736.  
  1737.         SDP^.Status := (Word(VUartLSRGet) SHL 8) +
  1738.                        (    (VuartMSRGet)      );
  1739.  
  1740.  
  1741.         SDP^.Status := ( SDP^.Status AND ($FFFF-$0100-$2000) );
  1742.  
  1743.         If VUartIsRXReady Then
  1744.           Inc( SDP^.Status, $0100 );
  1745.  
  1746.         If VuartIsTXReady Then
  1747.           Inc( SDP^.Status, $2000 );
  1748.  
  1749.  
  1750.  
  1751. (*
  1752.                      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  1753.  
  1754.                      1 2 4 5 1 3 6 1 2 5 1 2 4 8
  1755.                              6 2 4 2 5 1 0 0 0 1
  1756.                                    8 6 2 2 4 9 9
  1757.                                          4 8 6 2
  1758.  
  1759.   VUartIsRXReady := (BufferHead<>BufferTail);
  1760.   sbf_LSRRcvReady = 8;   { Received data ready                       }
  1761.  
  1762.                     $0100
  1763.  
  1764.  
  1765.   vuartistxready
  1766.   sbf_LSRXhReady  = 13;  { Transmit hold register empty              }
  1767.  
  1768.                     $2000
  1769.  
  1770. *)
  1771.  
  1772.  
  1773.       END;
  1774.  
  1775.  
  1776.  
  1777.  
  1778.       {--------}
  1779.  
  1780.       {--------}
  1781.       {--------}
  1782.       {--------}
  1783.  
  1784.       {--------}
  1785.  
  1786.       SDFDTROnOff:
  1787.       BEGIN
  1788.  
  1789.         If SDP^.OnOff Then
  1790.           VUartDTROn
  1791.         ELSE
  1792.           VUartDTROff;
  1793.  
  1794.         SDP^.Error := 0;
  1795.  
  1796.       END;
  1797.  
  1798.       {--------}
  1799.  
  1800.       SDFBreakOnOff:
  1801.       BEGIN
  1802.  
  1803.         SDP^.Error := 0;
  1804.  
  1805.       END;
  1806.  
  1807.       {--------}
  1808.  
  1809.       SDFRTSOnOff:
  1810.       BEGIN
  1811. (*
  1812.         If SDP^.OnOff Then
  1813.           VUartRTSOn
  1814.         ELSE
  1815.           VUartRTSOff;
  1816. *)
  1817.         SDP^.Error := 0;
  1818.  
  1819.       END;
  1820.  
  1821.       {--------}
  1822.       {--------}
  1823.       {--------}
  1824.  
  1825.  
  1826.  
  1827.       SDFFlushOutBuff:
  1828.       BEGIN
  1829.  
  1830.         VUartOutFlush;
  1831.  
  1832.         SDP^.Error := 0;
  1833.  
  1834.       END;
  1835.  
  1836.       {--------}
  1837.  
  1838.       SDFPurgeOutBuff:
  1839.       BEGIN
  1840.  
  1841.         VUartOutPurge;
  1842.  
  1843.         SDP^.Error := 0;
  1844.  
  1845.       END;
  1846.  
  1847.       {--------}
  1848.  
  1849.       SDFPurgeInBuff:
  1850.       BEGIN
  1851.  
  1852.         VUartInPurge;
  1853.  
  1854.         SDP^.Error := 0;
  1855.  
  1856.       END;
  1857.  
  1858.       {--------}
  1859.  
  1860.       sdfGetOutBuffInfo:
  1861.       BEGIN
  1862.  
  1863.  
  1864.         { we can only hold 1 outgoing char }
  1865.  
  1866.         SDP^.BuffInfo.Size       := 1;
  1867.  
  1868.         { is the output ready? }
  1869.  
  1870.         If VUartisTXReady Then
  1871.         BEGIN
  1872.           SDP^.BuffInfo.Used     := 0;
  1873.           SDP^.BuffInfo.Free     := 1;
  1874.         END
  1875.         ELSE
  1876.         BEGIN
  1877.           SDP^.BuffInfo.Used     := 1;
  1878.           SDP^.BuffInfo.Free     := 0;
  1879.         END;
  1880.  
  1881.         SDP^.BuffInfo.Changeable := FALSE;
  1882.  
  1883.         SDP^.Error               := 0;
  1884.  
  1885.       END;
  1886.  
  1887.       {--------}
  1888.  
  1889.       sdfSetOutBuffInfo:
  1890.       BEGIN
  1891.  
  1892.  
  1893.         SDP^.Error               := $FFFF0000;
  1894.  
  1895.       END;
  1896.  
  1897.       {--------}
  1898.  
  1899.       sdfGetInBuffInfo:
  1900.       BEGIN
  1901.  
  1902.         SDP^.BuffInfo.Size       := SizeOf( Buffer );
  1903.  
  1904.         ASM CLI; END;
  1905.  
  1906.         If BufferTail<=BufferHead Then
  1907.         BEGIN
  1908.  
  1909.           SDP^.BuffInfo.Used := BufferHead-BufferTail;
  1910.           SDP^.BuffInfo.Free := SizeOf( Buffer ) - SDP^.BuffInfo.Used;
  1911.  
  1912.         END
  1913.         ELSE
  1914.         BEGIN
  1915.  
  1916.           SDP^.BuffInfo.Used := (Sizeof( Buffer ) - Succ(BufferTail)) +
  1917.                                 (Succ(BufferHead)                     );
  1918.  
  1919.           SDP^.BuffInfo.Free := SizeOf( Buffer ) - SDP^.BuffInfo.Used;
  1920.  
  1921.         END;
  1922.  
  1923.         ASM STI; END;
  1924.  
  1925.         SDP^.BuffInfo.Changeable := FALSE;
  1926.         SDP^.Error               := 0;
  1927.  
  1928.       END;
  1929.  
  1930.       {--------}
  1931.  
  1932.       sdfSetInBuffInfo:
  1933.       BEGIN
  1934.  
  1935.         SDP^.Error := $FFFF0000;
  1936.  
  1937.       END;
  1938.  
  1939.       {--------}
  1940.       {--------}
  1941.       {--------}
  1942.  
  1943.  
  1944.  
  1945.       SDFEventProcNew:
  1946.       BEGIN
  1947.       END;
  1948.  
  1949.       {--------}
  1950.  
  1951.       SDFEventProcOff:
  1952.       BEGIN
  1953.       END;
  1954.  
  1955.       {--------}
  1956.  
  1957.       SDFEventProcOn:
  1958.       BEGIN
  1959.       END;
  1960.  
  1961.       {--------}
  1962.  
  1963.       SDFEventProcDispose:
  1964.       BEGIN
  1965.       END;
  1966.  
  1967.       {--------}
  1968.  
  1969.       sdfEventProcMaskSet:
  1970.       BEGIN
  1971.  
  1972.         SDP^.Error := $FFFF0000;
  1973.  
  1974.       END;
  1975.  
  1976.       {--------}
  1977.       {--------}
  1978.       {--------}
  1979.  
  1980.  
  1981.       SDFWriteCh:
  1982.       BEGIN
  1983.  
  1984.         VUartWriteChar( SDP^.CH );
  1985.  
  1986.         SDP^.Error := 0;
  1987.  
  1988.  
  1989.       END;
  1990.  
  1991.       {--------}
  1992.  
  1993.       SDFWriteBlock:
  1994.       BEGIN
  1995.  
  1996.         VUartWriteBlock( SDP^.Buf,
  1997.                          SDP^.Count  );
  1998.  
  1999.         SDP^.Error := 0;
  2000.  
  2001.       END;
  2002.  
  2003.       {--------}
  2004.  
  2005.       SDFReadCh:
  2006.       BEGIN
  2007.  
  2008.         SDP^.Error := 0;
  2009.  
  2010.         SDP^.CH := VUartReadChar;
  2011.  
  2012.       END;
  2013.  
  2014.       {--------}
  2015.  
  2016.       SDFReadBlock:
  2017.       BEGIN
  2018.  
  2019.         VUartReadBlock( SDP^.Buf,
  2020.                         SDP^.Count     );
  2021.  
  2022.         SDP^.Error := 0;
  2023.  
  2024.       END;
  2025.  
  2026.       {--------}
  2027.  
  2028.       sdfPeekCh:
  2029.       BEGIN
  2030.  
  2031.         SDP^.Error := $FFFF0000;
  2032.  
  2033.       END;
  2034.  
  2035.       {--------}
  2036.  
  2037.     End;
  2038.  
  2039.   END;
  2040.  
  2041. END;
  2042.  
  2043. {────────────────────────────────────────────────────────────────────────────}
  2044. {────────────────────────────────────────────────────────────────────────────}
  2045. {────────────────────────────────────────────────────────────────────────────}
  2046.  
  2047.  
  2048. BEGIN
  2049.  
  2050.   ExitSave    := ExitProc;
  2051.   ExitProc    := @ExitUnit;
  2052.   UartIsOpen  := FALSE;
  2053.   Overflow    := FALSE;
  2054.   CtsRtsOn    := TRUE;
  2055.  
  2056. END.
  2057.  
  2058.  
  2059.